/**   
 * @Title: SetCityActivity.java
 * @Package com.willter.weather.app
 * @Description: TODO(描述文件)
 * 		<p>
 * @author willter
 * @date 2012-9-14
 */
package com.willter.weather.app;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.StringReader;
import java.util.List;
import java.util.Map;

import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.appwidget.AppWidgetManager;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.content.res.Configuration;
import android.database.sqlite.SQLiteDatabase;
import android.location.Criteria;
import android.location.Location;
import android.location.LocationManager;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.BaseExpandableListAdapter;
import android.widget.ExpandableListView;
import android.widget.ExpandableListView.OnChildClickListener;
import android.widget.ListView;
import android.widget.RemoteViews;
import android.widget.TextView;
import android.widget.Toast;

import com.willter.weather.adapter.GPSListAdapter;
import com.willter.weather.adapter.MyListAdapter;
import com.willter.weather.dao.DBHelper;
import com.willter.weather.utils.LocationXMLParser;
import com.willter.weather.utils.WeaterInfoParser;
import com.willter.weather.utils.WebAccessTools;

/**
 * @ClassName: SetCityActivity
 * @Description: 设置城市UI界面
 *               <p>
 * @author willter
 * @date 2012-9-14
 */
public class SetCityActivity extends Activity {
	// 自动定位的列表
	private ListView gpsView;
	// 省份可伸缩性的列表
	private ExpandableListView provinceList;
	// 过滤文本输入框
	private TextView filterText;
	// 过滤文本输入框
	public static final String CITY_CODE_FILE = "city_code";
	// 城市编码
	private String[][] cityCodes;
	// 省份
	private String[] groups;
	// 省份对应的城市
	private String[][] childs;
	// 自定义伸缩列表的适配器
	private MyListAdapter adapter;
	// 记录应用程序widget的ID
	private int mAppWidgetId = AppWidgetManager.INVALID_APPWIDGET_ID;
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.set_city);

		// tempMethod();

		gpsView = (ListView) findViewById(R.id.gps_view);
		provinceList = (ExpandableListView) findViewById(R.id.provinceList);
		
		gpsView.setAdapter(new GPSListAdapter(this));
		gpsView.setOnItemClickListener(new OnItemClickListener() {

			@Override
			public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
				TextView localeCity = (TextView) view.findViewById(R.id.locateCityText);
				localeCity.setText("正在定位...");

				// tempMethod();

				final LocateHandler handler = new LocateHandler(localeCity);
				// 添加一个线程处理定位
				new Thread() {
					@Override
					public void run() {
						Map<Integer, String> cityMap = getLocationCityInfo();
						// 记录匹配的城市索引
						int provinceIndex = -1;
						int cityIndex = -1;
						Bundle bundle = new Bundle();
						if (cityMap != null) {
							// 国家名
							String country = cityMap.get(LocationXMLParser.COUNTRYNAME);
							// 只查询中国地区的天气
							if (country != null && country.equals("中国")) {
								// 省份
								String province = cityMap.get(LocationXMLParser.ADMINISTRATIVEAREANAME);
								// 城市
								String city = cityMap.get(LocationXMLParser.LOCALITYNAME);
								// 区县
								String towns = cityMap.get(LocationXMLParser.DEPENDENTLOCALITYNAME);

								Log.i("GPS", "============" + province + "." + city + "." + towns + "==============");
								StringBuilder matchCity = new StringBuilder(city);
								matchCity.append(".").append(towns);
								for (int i = 0; i < groups.length; i++) {
									if (groups[i].equals(province)) {
										provinceIndex = i;
										break;
									}
								}
								// 先从区县开始查找匹配的地区
								for (int j = 0; j < childs[provinceIndex].length; j++) {
									if (childs[provinceIndex][j].equals(matchCity.toString())) {
										cityIndex = j;
										break;
									}
								}
								// 如果未匹配成功,则换为从城市中查找
								if (cityIndex == -1) {
									for (int j = 0; j < childs[provinceIndex].length; j++) {
										if (childs[provinceIndex][j].equals(city)) {
											cityIndex = j;
											// 匹配成功，则退出循环
											break;
										}
									}
								}
							}
						}
						// 将其用bundle封装，用于传给Handler
						bundle.putInt("provinceIndex", provinceIndex);
						bundle.putInt("cityIndex", cityIndex);
						// 由handler处理
						Message msg = new Message();
						msg.setData(bundle);
						handler.sendMessage(msg);
					}
				}.start();
			}
		});

		// 文本框添加事件
		filterText = (TextView) findViewById(R.id.filterField);
		filterText.addTextChangedListener(new TextWatcher() {

			@Override
			public void onTextChanged(CharSequence paramCharSequence, int paramInt1, int paramInt2, int paramInt3) {
			}

			@Override
			public void beforeTextChanged(CharSequence paramCharSequence, int paramInt1, int paramInt2, int paramInt3) {
			}

			@Override
			public void afterTextChanged(Editable paramEditable) {
				CharSequence filterContent = filterText.getText();
				adapter.getFilter().filter(filterContent);
			}
		});

		// 得到MainActivity或Widget传过来的intent
		Intent intent = getIntent();
		// 是否第一次运行
		boolean isFirstRun = intent.getBooleanExtra("isFirstRun", false);
		
		Bundle extras = intent.getExtras();
		if (null != extras) {
			mAppWidgetId = extras.getInt(AppWidgetManager.EXTRA_APPWIDGET_ID, AppWidgetManager.INVALID_APPWIDGET_ID);
			if (mAppWidgetId != AppWidgetManager.INVALID_APPWIDGET_ID) {
				SharedPreferences sp = getSharedPreferences(CITY_CODE_FILE, MODE_PRIVATE);
				if (sp.getString("code", null) == null) {
					// 不存在城市码，第一次运行
					isFirstRun = true;
				} else {
					AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(SetCityActivity.this);
					RemoteViews views = new RemoteViews(SetCityActivity.this.getPackageName(), R.layout.widget_layout);

					// 得到城市码
					String cityCode = sp.getString("code", "");
					if (cityCode != null && cityCode.trim().length() > 0) {
						Log.i("widget", "===================update  weather===========================");
						// 更新widget
						WeatherWidget.updateAppWidget(views, SetCityActivity.this, appWidgetManager, cityCode);
					}

					appWidgetManager.updateAppWidget(mAppWidgetId, views);
					// 设置成功，返回
					Intent resultValue = new Intent();
					resultValue.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, mAppWidgetId);
					setResult(RESULT_OK, resultValue);
					// 结束当前的Activity
					finish();
					return;
				}
			}
		}

		if (isFirstRun) {
			// 导入城市编码数据库
			importInitDatabase();

			// 显示一个对话框说明第一次运行
			AlertDialog.Builder builder = new AlertDialog.Builder(this);
			builder.setMessage("由于本程序是第一次运行，请选择您需要了解天气的城市").setPositiveButton("确定", null);
			AlertDialog dialog = builder.create();
			dialog.show();
		}

		// 增强用户体验，在加载城市列表时显示进度对话框
		final ProgressDialog dialog = getProgressDialog("", "正在加载城市列表...");
		dialog.show();
		// 伸缩性列表的加载处理类
		final MyHandler mHandler = new MyHandler();
		new Thread(new Runnable() {
			public void run() {
				// 查询处理数据库,装载伸展列表
				DBHelper dbHelper = new DBHelper(SetCityActivity.this, "db_weather.db");
				groups = dbHelper.getAllProvinces();
				List<String[][]> result = dbHelper.getAllCityAndCode(groups);
				childs = result.get(0);
				cityCodes = result.get(1);
				// 交给Handler对象加载列表
				Message msg = new Message();
				mHandler.sendMessage(msg);
				dialog.cancel();
				dialog.dismiss();
			}
		}).start();
	}
	
//	@Override
//	public void onConfigurationChanged(Configuration newConfig) {
//		if (this.getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) {
//			Toast.makeText(this, "横屏", Toast.LENGTH_LONG);
//		}else if (this.getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {
//			Toast.makeText(this, "竖屏", Toast.LENGTH_LONG);
//		}
//		setContentView(R.layout.set_city);
//	}

	public void importInitDatabase() {
		// 数据库的目录
		String dirPath = "/data/data/com.willter.weather.app/databases";
		File dir = new File(dirPath);
		if (!dir.exists()) {
			dir.mkdir();
		}
		// 数据库文件
		File dbfile = new File(dir, "db_weather.db");
		try {
			if (!dbfile.exists()) {
				dbfile.createNewFile();
			}
			// 加载导入的数据库
			InputStream is = this.getApplicationContext().getResources().openRawResource(R.raw.db_weather);
			FileOutputStream fos = new FileOutputStream(dbfile);
			byte[] buffer = new byte[is.available()];
			is.read(buffer);
			fos.write(buffer);
			is.close();
			fos.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	/**
	 * @Title: getProgressDialog
	 * @Description: 创建进度对话框
	 *               <p>
	 * @author willter
	 * @date 2012-9-14
	 *       <p>
	 * @param title
	 *            标题
	 * @param content
	 *            内容
	 * @return 进度对话框
	 */
	public ProgressDialog getProgressDialog(String title, String content) {
		ProgressDialog dialog = new ProgressDialog(this);
		dialog.setTitle(title);
		dialog.setIndeterminate(true);
		dialog.setMessage(content);
		dialog.setCancelable(true);

		return dialog;
	}

	/**
	 * @Title: getLocationCityInfo
	 * @Description: GPS定位获取当前城市信息
	 *               <p>
	 * @author willter
	 * @date 2012-9-14
	 *       <p>
	 * @return
	 */
	public synchronized Map<Integer, String> getLocationCityInfo() {
		LocationManager locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);

		// 设置一个Criteria标准用于过滤LocationProvider
		Criteria criteria = new Criteria();
		// 设置不需要高度信息
		criteria.setAltitudeRequired(false);
		// 设置不需要方位信息
		criteria.setBearingRequired(false);
		// 设置得到的为免费
		// criteria.setCostAllowed(false);

		// 得到最好的可用的Provider
		String provider = locationManager.getBestProvider(criteria, true);
		// 得到当前的位置对象
		Location location = locationManager.getLastKnownLocation(provider);
		if (null != location) {
			double latitude = location.getLatitude(); // 经度
			double longitude = location.getLongitude(); // 维度

			WebAccessTools webTools = new WebAccessTools(this);
			String url = (new StringBuffer("http://maps.google.cn/maps/geo?output=xml&q=").append(latitude).append(",").append(longitude))
					.toString();
			String addressContext = webTools.getWebContent(url);
			// 解析地址信息
			SAXParserFactory spf = SAXParserFactory.newInstance();

			try {
				SAXParser parser = spf.newSAXParser();
				XMLReader reader = parser.getXMLReader();
				LocationXMLParser handler = new LocationXMLParser();
				reader.setContentHandler(handler);

				StringReader read = new StringReader(addressContext);
				// 创建新的输入源SAX 解析器将使用 InputSource 对象来确定如何读取 XML 输入
				InputSource source = new InputSource(read);

				// 开始解析
				reader.parse(source);
				if (handler.hasAddress()) {
					return handler.getDetailAddress();
				}
			} catch (ParserConfigurationException e) {
				e.printStackTrace();
			} catch (SAXException e) {
				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}

		return null;
	}

	// 用户处理装载伸缩性列表的处理类
	private class MyHandler extends Handler {

		@Override
		public void handleMessage(Message msg) {
			super.handleMessage(msg);

			// 在伸缩性列表展示数据库中的省份和城市
			adapter = new MyListAdapter(SetCityActivity.this, provinceList, groups, childs);
			provinceList.setAdapter(adapter);

			// 为其子列表选项添加单击事件
			provinceList.setOnChildClickListener(new OnChildClickListener() {

				@Override
				public boolean onChildClick(ExpandableListView parent, View v, int groupPosition, int childPosition, long id) {
					// 获取城市名
					String cityName = (String) adapter.getChild(groupPosition, childPosition);
					// 获取城市名对应的城市码
					DBHelper dbHelper = new DBHelper(SetCityActivity.this, "db_weather.db");
					String cityCode = dbHelper.getCityCodeByName(cityName);

					Dialog dialog = getProgressDialog("", "正在加载天气...");
					dialog.show();
					
					GoToMainActivity thread = new GoToMainActivity(cityCode, dialog);
					thread.start();

					return false;
				}
			});
		}
	}

	// 处理定位信息的内部类
	private class LocateHandler extends Handler {
		private TextView textView;

		public LocateHandler(TextView textView) {
			super();
			this.textView = textView;
		}

		@Override
		public void handleMessage(Message msg) {
			Bundle data = msg.getData();
			int provinceIndex = data.getInt("provinceIndex");
			int cityInde = data.getInt("cityIndex");
			// 判断定位匹配是否成功
			if (provinceIndex >= 0 && provinceIndex < groups.length && cityInde >= 0 && cityInde < childs[provinceIndex].length) {
				// 显示定位的城市
				textView.setText(childs[provinceIndex][cityInde]);

				// 自定跳转到天气的显示界面MainActivity
				Dialog dialog = getProgressDialog("", "正在加载天气...");
				dialog.show();
				GoToMainActivity thread = new GoToMainActivity(cityCodes[provinceIndex][cityInde], dialog);
				thread.start();
			} else {
				textView.setText("定位失败！");
			}
		}
	}

	// 开启线程跳转到MainActivity
	private class GoToMainActivity extends Thread {
		// 跳转的城市码
		private String cityCode;
		// 跳转显示的对话框
		private Dialog dialog;

		public GoToMainActivity(String cityCode, Dialog dialog) {
			//super();
			this.cityCode = cityCode;
			this.dialog = dialog;
		}

		@Override
		public void run() {
			// 得到一个私有的SharedPreferences文件编辑对象
			Editor edit = getSharedPreferences(CITY_CODE_FILE, MODE_PRIVATE).edit();
			// 将城市码保存
			edit.putString("code", cityCode);
			edit.commit();

			// 通过判断得到的widgetId是否有效来判断是跳转到MainActivity或Widget
			if (mAppWidgetId == AppWidgetManager.INVALID_APPWIDGET_ID) {
				// 设置成功回退到天气情况显示Activity
				Intent intent = getIntent();
				// 更新天气
				intent.putExtra("updateWeather", true);
				SetCityActivity.this.setResult(0, intent);
			} else {
				AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(SetCityActivity.this);
				RemoteViews views = new RemoteViews(SetCityActivity.this.getPackageName(), R.layout.widget_layout);
				// 更新widget
				WeatherWidget.updateAppWidget(views, SetCityActivity.this, appWidgetManager, cityCode);
				appWidgetManager.updateAppWidget(mAppWidgetId, views);
				// 设置成功
				Intent resultValue = new Intent();
				resultValue.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, mAppWidgetId);
				setResult(RESULT_OK, resultValue);
			}

			SetCityActivity.this.finish();
			dialog.cancel();
			dialog.dismiss();
		}
	}

	/**
	 * @Title: tempMethod
	 * @Description: 创建数据库
	 *               <p>
	 * @author willter
	 * @date 2012-9-17
	 *       <p>
	 */
	public void tempMethod() {
		// ==================================for
		// test==========================================
		WebAccessTools webTools = new WebAccessTools(this);
		// 得到访问网络的内容
		String webContent = webTools.getWebContent("http://m.weather.com.cn/data5/city.xml");

		// 第一次解析得到的为省份或一级直辖市
		String[][] provinces = WeaterInfoParser.parseCity(webContent);
		String[] groups = new String[provinces.length];
		String[][] childs = new String[provinces.length][];
		String[][] cityCode = new String[provinces.length][];
		for (int i = 0; i < provinces.length; i++) {
			groups[i] = provinces[i][1];
			// 由省份码来得到城市码
			StringBuffer urlBuilder = new StringBuffer("http://m.weather.com.cn/data5/city");
			urlBuilder.append(provinces[i][0]);
			urlBuilder.append(".xml");
			webContent = webTools.getWebContent(urlBuilder.toString());
			String[][] citys = WeaterInfoParser.parseCity(webContent);
			// 用于保存所的有towns
			String[][][] towns = new String[citys.length][][];
			// 计算总的城镇数
			int sum = 0;
			for (int j = 0; j < citys.length; j++) {
				// 由城市码来得到地方码
				urlBuilder = new StringBuffer("http://m.weather.com.cn/data5/city");
				urlBuilder.append(citys[j][0]);
				urlBuilder.append(".xml");
				webContent = webTools.getWebContent(urlBuilder.toString());
				towns[j] = WeaterInfoParser.parseCity(webContent);
				sum = sum + towns[j].length;
			}

			childs[i] = new String[sum];
			cityCode[i] = new String[sum];

			sum = 0;
			for (int j = 0; j < citys.length; j++) {
				for (int n = 0; n < towns[j].length; n++) {
					if (n == 0)
						childs[i][sum] = towns[j][n][1];
					else
						childs[i][sum] = towns[j][0][1] + "." + towns[j][n][1];

					urlBuilder = new StringBuffer("http://m.weather.com.cn/data5/city");
					urlBuilder.append(towns[j][n][0]);
					urlBuilder.append(".xml");

					webContent = webTools.getWebContent(urlBuilder.toString());
					String[][] code = WeaterInfoParser.parseCity(webContent);
					cityCode[i][sum] = code[0][1];
					sum = sum + 1;
				}
			}
			urlBuilder = null;
		}

		BaseExpandableListAdapter adapter = new MyListAdapter(this, provinceList, groups, childs);
		provinceList.setAdapter(adapter);

		// ============================Create
		// Database================================
		// 打开或创建一个数据库
		String path = "/data" + Environment.getDataDirectory().getAbsolutePath() + "/com.willter.app.weather/db_weather.db";

		SQLiteDatabase database = SQLiteDatabase.openOrCreateDatabase(path, null);
		// 创建一个省份表
		String sql = "create table provinces (_id integer primary key autoincrement, name text)";
		database.execSQL(sql);

		// 创建城市表
		sql = "create table citys (_id integer primary key autoincrement, province_id integer, name text, city_num text)";
		database.execSQL(sql);

		// 插入省份数据
		ContentValues cv = null;
		for (int i = 0; i < provinces.length; i++) {
			cv = new ContentValues();
			cv.put("name", provinces[i][1]);
			database.insert("provinces", null, cv);
		}
		// 插入城市数据
		for (int i = 0; i < childs.length; i++) {
			for (int j = 0; j < childs[i].length; j++) {
				cv = new ContentValues();
				cv.put("province_id", i);
				cv.put("name", childs[i][j]);
				cv.put("city_num", cityCode[i][j]);
				database.insert("citys", null, cv);
			}
		}
		cv = null;
		database.close();
	}
}
